package cn.hpclub.server.controller.admin;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfinal.aop.Before;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.render.JsonRender;
import com.jfinal.upload.UploadFile;

import cn.hpclub.server.constant.Constant;
import cn.hpclub.server.model.MemberOrg;
import cn.hpclub.server.model.Organization;
import cn.hpclub.server.model.Website;
import cn.hpclub.server.service.MemberOrgService;
import cn.hpclub.server.service.ds.Common;
import cn.hpclub.server.service.ds.DsLog;
import cn.hpclub.server.util.InterfaceUtil;
import cn.hpclub.server.util.QueryHelper;
import cn.hpclub.server.util.excel.ExcelLogs;
import cn.hpclub.server.util.excel.ExcelUtil;
import cn.hpclub.server.util.excel.ExportUtils;

// @API("/ProductServer/Product")
public class MemberOrgController extends BaseAdminController<MemberOrg>{
    private static final Logger logger            = LoggerFactory.getLogger(MemberOrgController.class);
    private static final String HTML_MEMBER_LIST  = "/admin/member.tpl";
    private static final String HTML_MEMBER_QUERY = "/admin/member_query.tpl";
    private static final String URL_TEMPLATE      = "/template/admin/file/员工导入模版-大掌柜.xls";
    private static final String URL_TEMPLATE_EMP  = "/template/admin/file/补登工号模板.xls";
    private static final String MEMBER_DIR        = "member/";
    private static final String ORG_ID            = "org_id";
    private static final String ORG_LIST          = "orgList";

    public void list(){
        // 给筛选项渠道类型赋值
        setAttr("class_list", Website.dao.getWebsite(true));

        // 给筛选项所属机构赋值
        int defaultOrgId = initOrgTree();
        // 搜索字段
        ConcurrentHashMap<String, String> searchInfo = getSearchInfo();
        if(searchInfo.get(ORG_ID) == null){
            // 如果是第一次，给选中的机构赋值为默认的顶级机构。
            searchInfo.put(ORG_ID, String.valueOf(defaultOrgId));
        }
        QueryHelper helper = MemberOrgService.service.listQueryHelper(searchInfo);
        findByPageForSearch(helper.getSelect(), helper.getSqlExceptSelect());

        setAttrs(searchInfo);
        render(HTML_MEMBER_LIST);
    }

    /*
     * private int initOrgTree(){ List<Entry<String, String>> orgList =
     * InterfaceUtil.getOrgList(); setAttr(ORG_LIST, orgList); if(orgList.size()
     * > 0){ return Integer.parseInt(orgList.get(0).getValue()); } else{ return
     * 0; } }
     */

    @Before(Tx.class)
    public void upload(){
        String resultMsg = null;
        int status = 1;
        try{
            resultMsg = importMember();
        }
        catch(FileNotFoundException e){
            e.printStackTrace();
            status = 0;
            resultMsg = "文件不存在";
        }
        catch(OfficeXmlFileException | EncryptedDocumentException | InvalidFormatException e){
            e.printStackTrace();
            resultMsg = "格式错误，请上传excel 2003/2007格式文件";
            status = 0;
        }
        catch(Exception e){
            e.printStackTrace();
            resultMsg = "服务器处理故障";
            status = 0;
        }
        finally{
            Map<String, Object> jsonMap = buildUploadReturnMsg(status, resultMsg);
            render(new JsonRender(jsonMap).forIE());
        }
    }

    /**
     * @Title: importMember
     * @Description:TODO
     * @return
     * @throws FileNotFoundException
     * @throws InvalidFormatException
     * @throws Exception
     *             String
     */

    private String importMember() throws FileNotFoundException, InvalidFormatException, Exception{
        int successCount = 0;
        String errorMsg = "";
        UploadFile uf = getFile();
        InputStream inputStream = null;
        inputStream = new FileInputStream(uf.getFile());

        ExcelLogs logs = new ExcelLogs();
        Collection<Map> importExcel = ExcelUtil.importExcel(Map.class, inputStream, "yyyy/MM/dd HH:mm:ss", logs, 0);
        int totalSize = importExcel.size();
        int i = 1;
        for(Map<?, ?> m : importExcel){
            String itemErrorMsg = saveorUpdateData(m, i);
            if(itemErrorMsg == null){
                successCount++;
            } else{
                errorMsg += itemErrorMsg;
            }
            i++;
        }
        int failedCount = totalSize - successCount;
        if((failedCount > 0) && (errorMsg.length() > 200)){
            errorMsg = errorMsg.substring(0, 200) + "\r\n。。。。。。";
        }
        return "成功：" + successCount + "条," + "失败：" + failedCount + "条。"
                + ((failedCount > 0 || (totalSize == 0)) ? errorMsg : "");
    }

    @Before(Tx.class)
    public void upload4emp(){
        String resultMsg = null;
        int status = 1;

        try{
            resultMsg = importMemberEmpcode();
        }
        catch(FileNotFoundException e){
            e.printStackTrace();
            status = 0;
            resultMsg = "文件不存在";
        }
        catch(OfficeXmlFileException | EncryptedDocumentException | InvalidFormatException e){
            e.printStackTrace();
            status = 0;
            resultMsg = "格式错误，请上传excel 2003/2007格式文件";
        }
        catch(Exception e){
            e.printStackTrace();
            status = 0;
            resultMsg = "服务器处理故障";
        }
        finally{
            Map<String, Object> jsonMap = buildUploadReturnMsg(status, resultMsg);
            render(new JsonRender(jsonMap).forIE());
        }

    }

    /**
     * @Title: importMemberEmpcode
     * @Description:TODO
     * @return
     * @throws FileNotFoundException
     * @throws InvalidFormatException
     * @throws Exception
     *             String
     */

    private String importMemberEmpcode() throws FileNotFoundException, InvalidFormatException, Exception{
        int successCount = 0;
        int totalSize = 0;
        String errorMsg = "";
        UploadFile uf = getFile();
        InputStream inputStream = null;
        inputStream = new FileInputStream(uf.getFile());

        ExcelLogs logs = new ExcelLogs();
        Collection<Map> importExcel = ExcelUtil.importExcel(Map.class, inputStream, "yyyy/MM/dd HH:mm:ss", logs, 0);
        totalSize = importExcel.size();
        int i = 1;
        for(Map<?, ?> m : importExcel){
            String itemErrorMsg = updateEmpCode(m, i);
            if(itemErrorMsg == null){
                successCount++;
            } else{
                errorMsg += itemErrorMsg;
            }
            i++;
        }
        int failedCount = totalSize - successCount;
        if((failedCount > 0) && (errorMsg.length() > 200)){
            errorMsg = errorMsg.substring(0, 200) + "\r\n。。。。。。";
        }
        return "成功：" + successCount + "条," + "失败：" + failedCount + "条。"
                + ((failedCount > 0 || (totalSize == 0)) ? errorMsg : "");
    }

    public void template(){
        renderFile(URL_TEMPLATE);
    }

    public void template4emp(){
        renderFile(URL_TEMPLATE_EMP);
    }

    @Before(Tx.class)
    public void export(){
        int topId = InterfaceUtil.getIdTop();
        String citySql = InterfaceUtil.getCitySql("member.org_id");
        String quxianSql = InterfaceUtil.getAreaSql("member.org_id");
        String sqlSelect = " select member.user_name as user_name,member.name as name,member.mobile as mobile,member.org_id as org_id, "
                + " org.NumCode as channel_code, date_format(member.reg_time,'%Y-%m-%d %H:%i:%s') as reg_time,(CASE member.member_type WHEN 1 THEN '店长' WHEN 2 THEN '店员' WHEN 3 THEN '泛店员' ELSE '未知' END) as member_type,"
                + " member.import_desc as import_desc,member.emp_code as emp_code,(CASE org.enabled WHEN 1 THEN '启用' ELSE '停用' END) as org_status, "
                + " org.DisplayName as channel_name, class_name as channel_type, " + quxianSql + " as quxian," + citySql
                + " as region, (CASE member.enabled WHEN 1 THEN '启用' ELSE '停用' END) as member_enabled ,"
                + " IF(orgType.orgIDTmp || orgType2.orgIDTmp2 , '是', '否') AS is_accounts_manager ";
        String sqlFilter = " FROM member_org as member, organization_class org_class,organization org"
                + " LEFT JOIN (SELECT id AS orgIDTmp FROM `organization` where (parentid=" + topId
                + " OR parentid IN (select id FROM organization WHERE  parentid=" + topId + "))) AS orgType "
                + " ON org.id = orgType.orgIDTmp "
                + " LEFT JOIN (SELECT org.id AS orgIDTmp2, orgcls.WebsiteId AS WebsiteIdType FROM organization org, organization_class orgcls WHERE org.WebsiteId = orgcls.id AND org.enabled=1 AND orgcls.enabled=1 AND org.id AND ( orgcls.WebsiteId LIKE '6%' OR orgcls.WebsiteId = '1000' OR orgcls.WebsiteId = '4800')) AS orgType2 ON org.id = orgType2.orgIDTmp2"
                + " where org.id=member.org_id and org.WebsiteId = org_class.id and member.is_deleted=0  and member.org_id in("
                + InterfaceUtil.getChlidOrgIdSql(InterfaceUtil.getOrgId(), Constant.MAX_ORG_LEVEL, true) + ") ";

        File file = getExportFile(generateFileName());
        FileOutputStream fos = null;
        final String[] headers = { "地区", "区县", "渠道编码", "渠道名称", "渠道类型", "门店状态", "人员状态", "真实姓名", "工号", "电话", "添加时间", "身份",
                "客户经理", "备注" };
        final String[] columns = { "region", "quxian", "channel_code", "channel_name", "channel_type", "org_status",
                "member_enabled", "name", "emp_code", "mobile", "reg_time", "member_type", "is_accounts_manager",
                "import_desc" };
        ExportUtils exportUtils = new ExportUtils(headers);
        try{
            fos = new FileOutputStream(file);
            long exportExcelStart = System.currentTimeMillis();
            int rowIndex = 1;
            int num = 0;
            long start = System.currentTimeMillis();
            while(true){
                List<?> list = Db.find(String.format("%s %s LIMIT %d, %d", sqlSelect, sqlFilter, num * 5000, 5000));
                logger.debug("num=" + num + ",size=" + list.size() + ",query use time:"
                        + (System.currentTimeMillis() - start));
                if(num > 1 && list.isEmpty()){
                    break;
                }
                exportUtils.exportExcel(columns, list, "", rowIndex);
                rowIndex += list.size();
                num++;
            }
            exportUtils.write(fos);
            renderFile(file);
            DsLog.log("人员数据导出:导出成功,导出文件:" + file.getName());
            logger.debug("人员数据导出:导出成功,导出文件:" + file.getName());
            logger.debug("exportExcel use time:" + (System.currentTimeMillis() - exportExcelStart));
        }
        catch(Exception e){
            logger.error(e.getMessage());
            file.delete();
        }
        finally{
            closeOutputStream(fos);
        }
    }

    private File getExportFile(String fileName){
        String filePath = getDirPath() + "/" + fileName;
        logger.debug("file url=" + filePath);
        File file = new File(filePath);
        return file;
    }

    private void closeOutputStream(OutputStream os){
        if(os != null){
            try{
                os.close();
            }
            catch(IOException e){
                e.printStackTrace();
            }
        }
    }

    @Before(Tx.class)
    public void delete(){
        softlyDeleteRecord(Constant.Table.MEMBER_ORG);
    }

    /**
     * @Title: softlyDeleteById
     * @Description:通用软删除，暂时还没有人用，所以也没有调
     * @param tableName
     *            void
     */
    private void softlyDeleteRecord(String tableName){
        logger.debug("delete");
        String[] ids = getParaValues("ids");
        StringBuffer sb = new StringBuffer();
        sb.append("update " + tableName + " set is_deleted = 1, modi_date=NOW() " + " where id in(");
        if(ids.length > 0){
            for(int i = 0; i < ids.length; i++){
                if(i == ids.length - 1){
                    sb.append("?");
                } else{
                    sb.append("?,");
                }
            }
            sb.append(")");
        } else{
            ajaxJsonErrorMessage("删除失败");
            return;
        }
        // System.out.println(tableName + " delete sb=" + sb);

        boolean success = Db.update(sb.toString(), (Object[])ids) > 0;
        if(success){
            ajaxJsonSuccessMessage("删除成功");
        } else{
            ajaxJsonErrorMessage("删除失败");
        }
    }

    @Before(Tx.class)
    public void changeStatus(){
        String id = getPara("id");
        String targetStatus = getPara("target_status");
        String sql = "";
        if(targetStatus.equalsIgnoreCase("1")){
            sql = "update member_org set enabled = 1 where id=? and is_deleted=0";
        } else{
            sql = "update member_org set enabled = 0 where id=? and is_deleted=0";
        }
        boolean success = Db.update(sql, id) > 0;
        if(success){
            if(targetStatus.equalsIgnoreCase("1")){
                ajaxJsonSuccessMessage("已启用");
            } else{
                ajaxJsonSuccessMessage("已停用");
            }
        } else{
            ajaxJsonErrorMessage("操作失败");
        }

    }

    /**
     * 泛店员锁定
     */
    @Before(Tx.class)
    public void changeLock(){
        String id = getPara("id");
        String targetStatus = getPara("target_status");
        String sql = "update member_org set is_lock = ? where id=?";
        boolean success = Db.update(sql, targetStatus, id) > 0;
        if(success){
            ajaxJsonSuccessMessage("1".equalsIgnoreCase(targetStatus) ? "已锁定" : "已解锁");
        } else{
            ajaxJsonErrorMessage("操作失败");
        }
    }

    String generateFileName(){
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String curTime = sdf.format(date);
        return "人员数据" + curTime + ".xlsx";
    }

    String getString(String fullString, int maxLen){
        // 为空
        if(StringUtils.isBlank(fullString)){
            return "";
        }

        // 为null
        if("null".equalsIgnoreCase(fullString)){
            return "";
        }

        if(fullString.length() > maxLen){
            return fullString.substring(0, maxLen);
        }

        // 长度小于，都直接返回
        return fullString;
    }

    private String updateEmpCode(Map<?, ?> data, int i) throws Exception{
        String errorMsg = "";
        String mobile = String.valueOf(data.get("手机号"));
        if(StringUtils.isBlank(mobile) || "null".equalsIgnoreCase(mobile)){
            errorMsg = "\r\n手机号不能为空";
            return errorMsg;
        }
        // 手机号工号去掉空格
        mobile = ExcelUtil.removeSpace(mobile);
        if(!isMobileNO(mobile)){
            errorMsg = "\r\n第" + i + "条：手机号码格式不正确";
            return errorMsg;
        }
        String empCode = getString(ExcelUtil.removeSpace(String.valueOf(data.get("工号"))), MemberOrg.MAX_EMPCODE_LEN);
        if(!isEmpCodeLegal(empCode)){
            errorMsg = "\r\n第" + i + "条：工号必须纯字母或数字";
            return errorMsg;
        }
        MemberOrg member = MemberOrg.dao.getMemberOrgbyUserName(mobile);
        Date now = new Date(new Date().getTime());
        if(member == null){
            errorMsg += "\r\n第" + i + "条:手机号码" + mobile + "不存在";
            return errorMsg;
        } else{
            // 若已经存在，但已经禁用，则提示错误。
            if(member.getBoolean(MemberOrg.IS_DELETED).booleanValue()){
                errorMsg += "\r\n第" + i + "条:账号" + mobile + "不存在";
                return errorMsg;
            }

            // 若已经存在，且当前可用状态，则 修改员工工号
            member.set(MemberOrg.EMP_CODE, empCode);
            member.set(MemberOrg.MODI_DATE, now);

            // 对于已经软删除的数据，重新导入时，更新数据并重新激活。并记录更新时间.
            // member.set(MemberOrg.IS_DELETED, 0);
            member.update();
            return null;
        }

    }

    public boolean isMobileNO(String mobiles){
        Pattern p = Pattern.compile(Constant.Regex.MOBILE);
        Matcher m = p.matcher(mobiles);
        return m.matches();
    }

    /**
     * @Title: isEmpCodeLegal
     * @Description:工号暂时允许为空。一旦不为空，则校验是否是字母数字组成
     * @param empcode
     * @return boolean
     */
    public boolean isEmpCodeLegal(String empcode){
        if((empcode == null) || ("".equals(empcode)) || ("null".equalsIgnoreCase((empcode)))){
            return true;
        }

        Pattern p = Pattern.compile(Constant.Regex.ALPHABETS_NUMBERS);
        Matcher m = p.matcher(empcode);
        return m.matches();
    }

    /**
     * @Title: saveorUpdateData
     * @Description:将一条excel数据解析保存到数据。
     * @param data，一条excel数据
     * @param i，第几条，用于合成errormsg
     * @return String 保存成功，返回null。保存失败，返回errorMsg.
     */
    private String saveorUpdateData(Map<?, ?> data, int i) throws Exception{
        String errorMsg = "";
        if(!validImportExcelCellData(data)){
            errorMsg = "\r\n第" + i + "条：姓名、渠道编码、手机号不能为空";
            return errorMsg;
        }
        // 手机号，工号，渠道编码去掉空格
        String mobile = ExcelUtil.removeSpace(String.valueOf(data.get("手机号")));
        if(!isMobileNO(mobile)){
            errorMsg = "\r\n第" + i + "条：手机号码格式不正确";
            return errorMsg;
        }
        String name = getString(String.valueOf(data.get("姓名")), MemberOrg.MAX_NAME_LEN);
        String empCode = getString(ExcelUtil.removeSpace(String.valueOf(data.get("工号"))), MemberOrg.MAX_EMPCODE_LEN);
        if(!isEmpCodeLegal(empCode)){
            errorMsg = "\r\n第" + i + "条：工号必须纯字母或数字";
            return errorMsg;
        }
        String orgCode = ExcelUtil.removeSpace(String.valueOf(data.get("渠道编码")));
        String type = String.valueOf(data.get("身份"));
        String remark = getString(String.valueOf(data.get("备注")), MemberOrg.MAX_DESC_LEN);
        Integer orgId = MemberOrg.dao.getOrgIdbyOrgCode(orgCode);
        if(orgId != null){
            MemberOrg member = MemberOrg.dao.getMemberOrgbyUserName(mobile);
            Date now = new Date(new Date().getTime());
            if(member == null){
                // 若不存在，则新增员工
                member = getModel(MemberOrg.class);
                member.set(MemberOrg.NAME, name);
                member.set(MemberOrg.EMP_CODE, empCode);
                member.set(MemberOrg.USER_NAME, mobile);
                member.set(MemberOrg.NICKNAME, mobile);
                member.set(MemberOrg.MOBILE, mobile);
                // member.set(MemberOrg.CHANNEL_CODE, orgCode);
                member.set(MemberOrg.MEMBER_TYPE, covertMemberType(type));
                member.set(MemberOrg.IMPORT_DESC, remark);
                member.set(MemberOrg.ORG_ID, orgId);
                String pwd = mobile.substring(mobile.length() - 6, mobile.length());
                member.set(MemberOrg.PASSWORD, DigestUtils.md5Hex(pwd));
                member.set(MemberOrg.REG_TIME, now);
                member.set(MemberOrg.MODI_DATE, now);
                member.set(MemberOrg.IS_DELETED, 0);
                member.save();
            } else{
                // 若已经存在，则 修改员工信息
                member.set(MemberOrg.NAME, name);
                member.set(MemberOrg.EMP_CODE, empCode);
                member.set(MemberOrg.USER_NAME, mobile);
                member.set(MemberOrg.MOBILE, mobile);
                // member.set(MemberOrg.CHANNEL_CODE, orgCode);
                member.set(MemberOrg.MEMBER_TYPE, covertMemberType(type));
                member.set(MemberOrg.IMPORT_DESC, remark);
                member.set(MemberOrg.ORG_ID, orgId);
                member.set(MemberOrg.MODI_DATE, now);

                // 已经删除的，重新导入，修改密码为默认密码。只要账号没有被删除，重复导入，都不修改密码。
                if(member.getBoolean(MemberOrg.IS_DELETED).booleanValue()){
                    String pwd = mobile.substring(mobile.length() - 6, mobile.length());
                    member.set(MemberOrg.PASSWORD, DigestUtils.md5Hex(pwd));
                }

                // 对于已经软删除的数据，重新导入时，更新数据并重新激活。并记录更新时间.
                member.set(MemberOrg.IS_DELETED, 0);
                member.update();
            }
            // 成功返回null
            return null;
        }
        errorMsg += "\r\n第" + i + "条:渠道编码"
                + (StringUtils.isBlank(orgCode) || ("null".equalsIgnoreCase(orgCode)) ? "为空" : (orgCode + "不存在"));
        return errorMsg;
    }

    private boolean validImportExcelCellData(Map<?, ?> data){
        String name = String.valueOf(data.get("姓名"));
        // System.out.println("1 name:" + name + "end");
        String mobile = String.valueOf(data.get("手机号"));
        String channelCode = String.valueOf(data.get("渠道编码"));
        if(StringUtils.isBlank(name) || "null".equalsIgnoreCase(name) || StringUtils.isBlank(mobile)
                || "null".equalsIgnoreCase(mobile) || StringUtils.isBlank(channelCode)
                || StringUtils.isBlank(channelCode)){
            logger.error("validImportExcelCellData data error");
            return false;
        }
        return true;
    }

    private int covertMemberType(String type){

        if(type.equalsIgnoreCase("店长")){
            return 1;
        }
        return 2;
    }

    /**
     * @Title: queryEmpCodeInfoIndex
     * @Description:工号查询Index void
     */
    public void queryEmpCodeInfoIndex(){
        setAttr("result", 0);
        render(HTML_MEMBER_QUERY);
    }

    /**
     * @Title: queryEmpCodeInfo
     * @Description:工号查询 void
     */
    public void queryEmpCodeInfo(){
        String cellphone = getPara("cellphone");
        setAttr("cellphone", cellphone);

        List<Entry<String, Object>> dbResultList = MemberOrgService.service.queryMemberInfoInDb(cellphone);
        List<Entry<String, Object>> dprResultList = MemberOrgService.service.queryEmpCodeInfoFromBOSS(cellphone);
        if(dbResultList.isEmpty() && dprResultList.isEmpty()){
            setAttr("result", 0);
        } else{
            setAttr("result", 1);
            setAttrs(dbResultList);
            setAttrs(dprResultList);
        }
        render(HTML_MEMBER_QUERY);
    }

    private void setAttrs(List<Entry<String, Object>> list){
        for(Entry<String, Object> entry : list){
            setAttr(entry.getKey(), entry.getValue());
        }
    }

    /**
     * @Title: getDirPath
     * @Description:获取文件存储目录
     * @return String
     */
    public String getDirPath(){
        String dirPath = Common.getRootDir() + MEMBER_DIR;
        Common.checkDir(dirPath);
        return dirPath;
    }

    public void dialog(){
        this.keepPara(Organization.KEYWORD);
        this.keepPara("queryType");
        int pageNumber = getParaToInt(Constant.Ui.PAGER_NUMBER, 1);
        logger.debug("pageNumber=" + pageNumber);
        int pageSize = getParaToInt(Constant.Ui.PAGER_SIZE, 10);
        String keyword = getPara(Organization.KEYWORD, "");

        String sqlSelect = "SELECT id, name, mobile, emp_code ";
        String orgFilter = InterfaceUtil.getChlidOrgIdSql(InterfaceUtil.getOrgId(), Constant.MAX_ORG_LEVEL, true);
        String sqlExpect = "FROM member_org WHERE member_type!=3 and is_deleted=0 and org_id IN" + orgFilter
                + " AND (name LIKE ? OR user_name LIKE ?)";
        setAttr(Constant.Ui.PAGER, Db.paginate(pageNumber, pageSize, sqlSelect, sqlExpect,
                                               new Object[] { "%" + keyword + "%", "%" + keyword + "%" }));
        render("/admin/member_dialog.tpl");
    }

    public void query(){
        dialog();
    }
}